package com.ztesoft.web.baseconfig.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ztesoft.core.common.Page;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.JsonUtil;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.arg.DmStrategyDataobjRelArg;
import com.ztesoft.web.baseconfig.db.arg.DmStrategyDataobjRelArg.DmStrategyDataobjRelCriteria;
import com.ztesoft.web.baseconfig.db.dao.DmStrategyDataobjRelDao;
import com.ztesoft.web.baseconfig.db.dao.SubTableDefineDao;
import com.ztesoft.web.baseconfig.db.po.ColumnNamePO;
import com.ztesoft.web.baseconfig.db.po.ColumnsRelationPO;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyDataobjRelPO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.baseconfig.db.po.DmTargetTablePO;
import com.ztesoft.web.baseconfig.db.po.SubTablePO;
import com.ztesoft.web.baseconfig.db.po.TableNamePO;
import com.ztesoft.web.baseconfig.db.po.TargetTablePO;
import com.ztesoft.web.baseconfig.service.IDmPlanService;
import com.ztesoft.web.baseconfig.service.IDmSrcTableService;
import com.ztesoft.web.baseconfig.service.IDmStrategyService;
import com.ztesoft.web.baseconfig.service.IDmTargetTableService;
import com.ztesoft.web.common.DMSConstant.Status;
import com.ztesoft.web.common.db.po.DmIndexInfoPO;
import com.ztesoft.web.resourcecheck.IdxCheck;
import com.ztesoft.web.resourcecheck.LModeCheck;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;

/**
 * <Description>dmsrctable管理 <br>
 * 
 * @author lin.jie <br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2015年8月20日 <br>
 * @since V1.0<br>
 * @see com.ztesoft.web.baseconfig.controller <br>
 */

@Controller
@RequestMapping("/baseconfig/dmsrctable")
public class DmSrcTableController {

	private static final ZTEsoftLogManager logger = ZTEsoftLogManager.getLogger(DmSrcTableController.class);

	@Autowired
	private IDmSrcTableService dmSrcTableService;
	@Autowired
	private IDmPlanService dmPlanService;
	@Autowired
	private IDmStrategyService dmStrategyService;
	@Autowired
	private IDmTargetTableService dmTargetTableService;
	
	@Autowired
	private IdxCheck idxCheck;
	@Autowired
	private LModeCheck lModeCheck;
	@Autowired
	private BaseInfoService baseInfoService;

	@Autowired
	private DmStrategyDataobjRelDao dmStrategyDataobjRelDao;
	@Autowired
	private SubTableDefineDao subTableDefineDao;

	@RequestMapping("index")
	public String index(Model model) {
		return "cleaner/baseconfig/jsp/dmSrcTable";
	}

	@RequestMapping("queryRecordByPage")
	@ResponseBody
	public Page<DmSrcTablePO> queryRecordByPage(DmSrcTablePO record, Page<DmSrcTablePO> resultPage)
			throws BaseAppException {
		resultPage = dmSrcTableService.selectByArgAndPage(record, resultPage);
		return resultPage;
	}

	/**
	 * 根据表名，在本地已经配置好的数据库中，查找
	 * 
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("searchTableName")
	@ResponseBody
	public DmStrategyPO searchTableName(DmSrcTablePO record) throws Exception {
		DmStrategyPO dsPO = new DmStrategyPO();
		record = dmSrcTableService.selectByTableNameForShow(record);
		dsPO.setDmSrcTablePO(record);
		if (record.getSourceDataId() == -1) {// 该源表正在被使用
			return dsPO;
		}
		dsPO.setDmTargetTablePOList(dmTargetTableService.selectByTableNameForShow(record));
		return dsPO;
	}

	/**
	 * 表名的模糊查询控件
	 * 
	 * @param tableName
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("searchTableNameForSelect")
	@ResponseBody
	public List<DmSrcTablePO> searchTableNameForSelect(@RequestParam(value = "term", required = true) String term)
			throws Exception {
		List<DmSrcTablePO> resultList = dmSrcTableService.searchTableNameForSelect(term);
		return resultList;
	}

	/**
	 * 验证表名是否存在，返回字段
	 * 
	 * @param record
	 * @return
	 * @throws BaseAppException
	 */
	@RequestMapping("stColumnsRelation")
	@ResponseBody
	public List<ColumnsRelationPO> stColumnsRelation(DmSrcTablePO record) throws BaseAppException, Exception {
		List<ColumnsRelationPO> columnsRelationPOList = new ArrayList<ColumnsRelationPO>();
		// 源字段
		List<ColumnNamePO> srcpoList = new ArrayList<ColumnNamePO>(Arrays.asList(dmSrcTableService.selectAllColumns(
				record.getDbLinkId(), record.getDbUserName(), record.getTableName().trim())));
		// 目标字段
		List<ColumnNamePO> targetpoList = new ArrayList<ColumnNamePO>(Arrays.asList(dmSrcTableService.selectAllColumns(
				record.getSubDbLinkId(), record.getSubDbUserName(),
				JsonUtil.toArray(record.getSubTableName(), TableNamePO.class)[0].getValue())));

		// 去除目标表中的DM_TASK_ID和DM_DETAIL_ID字段
		for (int i = 0; i < targetpoList.size(); i++) {
			if (targetpoList.get(i).getColumnName().equals("dm_task_id")) {
				targetpoList.remove(i);
				i--;
				continue;
			}
			if (targetpoList.get(i).getColumnName().equals("dm_detail_id")) {
				targetpoList.remove(i);
				i--;
				continue;
			}
		}
		// 源、目标一样的字段
		List<ColumnNamePO> theSameColpoList = new ArrayList<ColumnNamePO>();

		for (int i = 0; i < srcpoList.size(); i++) {
			for (int j = 0; j < targetpoList.size(); j++) {
				if (srcpoList.get(i).getValue().equals(targetpoList.get(j).getValue())
						&& srcpoList.get(i).getDataType() == targetpoList.get(j).getDataType()) {
					theSameColpoList.add(srcpoList.get(i));
					srcpoList.remove(i);
					i--;
					targetpoList.remove(j);
					j--;
					break;
				}
			}
		}
		for (int i = 0; i < theSameColpoList.size(); i++) {
			ColumnsRelationPO po = new ColumnsRelationPO();
			po.setSrc(theSameColpoList.get(i).getValue());
			po.setTarget(theSameColpoList.get(i).getValue());
			po.setSrcDateType(theSameColpoList.get(i).getDataType());
			po.setSrcColumnSize(theSameColpoList.get(i).getColumnSize());
			po.setTargetDateType(theSameColpoList.get(i).getDataType());
			po.setTargetColumnSize(theSameColpoList.get(i).getColumnSize());
			columnsRelationPOList.add(po);
		}
		for (int i = 0; i < srcpoList.size(); i++) {
			ColumnsRelationPO po = new ColumnsRelationPO();
			po.setSrc(srcpoList.get(i).getValue());
			po.setSrcDateType(srcpoList.get(i).getDataType());
			po.setSrcColumnSize(srcpoList.get(i).getColumnSize());
			columnsRelationPOList.add(po);
		}
		for (int i = 0; i < targetpoList.size(); i++) {
			if (i >= srcpoList.size()) {
				ColumnsRelationPO po = new ColumnsRelationPO();
				po.setTarget(targetpoList.get(i).getValue());
				po.setTargetDateType(targetpoList.get(i).getDataType());
				po.setTargetColumnSize(targetpoList.get(i).getColumnSize());
				columnsRelationPOList.add(po);
			} else {
				columnsRelationPOList.get(i + theSameColpoList.size()).setTarget(targetpoList.get(i).getValue());
				columnsRelationPOList.get(i + theSameColpoList.size()).setTargetDateType(
						targetpoList.get(i).getDataType());
				columnsRelationPOList.get(i + theSameColpoList.size()).setTargetColumnSize(
						targetpoList.get(i).getColumnSize());
			}
		}
		return columnsRelationPOList;
	}

	/**
	 * 验证主表表名是否存在，返回字段
	 * 
	 * @param record
	 * @return -1：已经配置过该表，-2：所选数据库中不存在该表
	 * @throws BaseAppException
	 */
	@RequestMapping("verifyTableName")
	@ResponseBody
	public DmSrcTablePO verifyTableName(DmSrcTablePO record) throws BaseAppException, Exception {
		record.setTableNameArray(JsonUtil.toArray(record.getTableName(), TableNamePO.class));
		String tableName = record.getTableNameArray()[0].getValue().toLowerCase();
		record.setTableName(tableName);
		List<DmSrcTablePO> dstPOList = dmSrcTableService.selectByTableName(record);
		if (dstPOList.size() != 0) {// 表名存在，验证是不是已经配置过该表
			// // 修改
			// if (record.getIsEdit() == 1
			// &&
			// Utils.notEmpty(dmSrcTableService.selectByPrimaryKey(record.getSourceDataId()))
			// &&
			// tableName.equals(dmSrcTableService.selectByPrimaryKey(record.getSourceDataId()).getTableName()))
			// {
			// } else {
			// record.setSourceDataId(-1);
			// return record;
			// }
			// // 新增
			// if (record.getIsEdit() == 0) {
			// record.setSourceDataId(-1);
			// return record;
			// }
			record.setSourceDataId(dstPOList.get(0).getSourceDataId());
			DmSrcTablePO dstPO = dmSrcTableService.selectByPrimaryKey(record.getSourceDataId());
			if (Utils.notEmpty(dstPO) && tableName.equalsIgnoreCase(dstPO.getTableName())) {
				if (record.getIsEdit() == 0) {// 新增
//					if (Status.DRAFT.toString().equals(dstPO.getState())
//							|| Status.DRAFT_OK.toString().equals(dstPO.getState())) {// 保存草稿后，马上再点击验证
//					} else {
						// 查看是已经有计划使用了，还是已经删除了，通过表名查询就行
						// 只需要查看是否和策略有关联
						DmStrategyDataobjRelArg dsdrArg = new DmStrategyDataobjRelArg();
						DmStrategyDataobjRelCriteria dsdrCriteria = dsdrArg.createCriteria();
						dsdrCriteria.andSourceDataIdEqualTo(record.getSourceDataId());
						dsdrCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
						List<DmStrategyDataobjRelPO> dsdrPOList = dmStrategyDataobjRelDao.selectByArg(dsdrArg);
						if (dsdrPOList.size() != 0) {// 说明有和策略关联，有计划在使用这源表
							record.setSourceDataId(-1);
						} else {// 已经配置过，但没有和策略关联，没有计划在使用
							record.setSourceDataId(-3);
						}
						return record;
//					}
				}
			} else {
				record.setSourceDataId(-1);
				return record;
			}
			// if (record.getIsEdit() == 1) {// 修改
			// if (Utils.isEmpty(dstPO) ||
			// !tableName.equalsIgnoreCase(dstPO.getTableName())) {
			// record.setSourceDataId(-1);
			// return record;
			// }
			// } else if (record.getIsEdit() == 0) {// 新增，还有一种情况：保存草稿后，马上再点击验证
			// if(){
			//
			// }
			// record.setSourceDataId(-1);
			// return record;
			// }
		}
		ColumnNamePO[] allColumns = dmSrcTableService.selectAllColumns(record.getDbLinkId(), record.getDbUserName(),
				tableName);
		if (allColumns.length == 0) {// 所选数据库中不存在该表
			record.setSourceDataId(-2);
			return record;
		}
		if ("-2".equals(allColumns[0].getValue()) && "-2".equals(allColumns[0].getColumnName())) {// 所选数据库中不存在该表
			record.setSourceDataId(-2);
			return record;
		}
		record.setAllColumns(allColumns);
		record.setPkColumns(dmSrcTableService.selectPkColumns(record.getDbLinkId(), record.getDbUserName(), tableName));

		// 表索引，锁模式，检测
		String[] dbConfig = baseInfoService.getDbConfig(record.getDbLinkId(), record.getDbUserName());
		record.setDbType(dbConfig[0]);
		// 表索引
		if (dbConfig[0].equals("oracle")) {// oracle
			tableName = tableName.toUpperCase();
		}
		List<DmIndexInfoPO> diiPOList = idxCheck.qryIdxForPO(record.getDbLinkId(), tableName, dbConfig);
		record.setDiiPOList(diiPOList);
		// 锁模式
		String lMode = "";
		if (dbConfig[0].equals("informix")) {// informix
			lMode = lModeCheck.qryIfxLMode(record.getDbLinkId(), tableName, dbConfig);
		}
		record.setLockMode(lMode);
		return record;
	}

	/**
	 * 验证从表表名是否存在，返回字段
	 * 
	 * @param record
	 * @return -1：已经配置过该表，-2：所选数据库中不存在该表
	 * @throws BaseAppException
	 */
	@RequestMapping("verifySubTableName")
	@ResponseBody
	public DmSrcTablePO verifySubTableName(DmSrcTablePO record) throws BaseAppException, Exception {
		record.setTableNameArray(JsonUtil.toArray(record.getTableName(), TableNamePO.class));
		record.setSubTableNameArray(JsonUtil.toArray(record.getSubTableName(), TableNamePO.class));
		String tableName = record.getTableNameArray()[0].getValue().toLowerCase();
		String subTableName = record.getSubTableNameArray()[0].getValue().toLowerCase();
		if (dmSrcTableService.selectByTableName(record).size() != 0) {// 已经配置过该分表
			record.setSourceDataId(-1);
			return record;
		}
		// 从表的所有字段
		ColumnNamePO[] subAllColumns = dmSrcTableService.selectAllColumns(record.getSubDbLinkId(),
				record.getSubDbUserName(), subTableName);
		if (subAllColumns.length == 0) {// 所选数据库中不存在该表
			record.setSourceDataId(-2);
			return record;
		}
		if ("-2".equals(subAllColumns[0].getValue()) && "-2".equals(subAllColumns[0].getColumnName())) {// 所选数据库中不存在该表
			record.setSourceDataId(-2);
			return record;
		}
		record.setSubAllColumns(subAllColumns);
		record.setPkColumns(dmSrcTableService.selectPkColumns(record.getDbLinkId(), record.getDbUserName(), tableName));
		
		// 表索引，锁模式，检测
		String[] dbConfig = baseInfoService.getDbConfig(record.getSubDbLinkId(), record.getSubDbUserName());
		record.setDbType(dbConfig[0]);
		// 表索引
		if (dbConfig[0].equals("oracle")) {// oracle
			subTableName = subTableName.toUpperCase();
		}
		List<DmIndexInfoPO> diiPOList = idxCheck.qryIdxForPO(record.getSubDbLinkId(), subTableName, dbConfig);
		record.setDiiPOList(diiPOList);
		// 锁模式
		String lMode = "";
		if (dbConfig[0].equals("informix")) {// informix
			lMode = lModeCheck.qryIfxLMode(record.getSubDbLinkId(), subTableName, dbConfig);
		}
		record.setLockMode(lMode);
		return record;
	}

	/**
	 * 脚本验证，返回sql语句
	 * 
	 * @param record
	 * @return
	 * @throws BaseAppException
	 */
	@RequestMapping("scriptVerify")
	@ResponseBody
	public String scriptVerify(DmTargetTablePO dttPO, DmSrcTablePO dstPO) throws BaseAppException, Exception {
		return dmSrcTableService.scriptVerify(dttPO, dstPO);
	}

	@RequestMapping("queryDmPlanIdDraft")
	@ResponseBody
	public List<DmSrcTablePO> queryDmPlanIdDraft(DmSrcTablePO record) throws BaseAppException {
		logger.debug("searchdmPlanId record begin...record=[{0}]", record);
		List<DmSrcTablePO> resultList = dmSrcTableService.selectByArgFormDraft(record);
		return resultList;
	}

	/**
	 * 根据Form表单里的条件返回dmPlanId,计划维护
	 * 
	 * @param record
	 * @return
	 * @throws BaseAppException
	 */
	@RequestMapping("queryDmPlanIdMaint")
	@ResponseBody
	public List<DmSrcTablePO> queryDmPlanIdMaint(DmSrcTablePO record) throws BaseAppException {
		logger.debug("searchdmPlanId record begin...record=[{0}]", record);
		List<DmSrcTablePO> resultList = dmSrcTableService.selectByArgFormMaint(record);
		return resultList;
	}

	@RequestMapping("add")
	@ResponseBody
	public DmSrcTablePO add(DmSrcTablePO record) throws BaseAppException, Exception {
		logger.debug("add record begin...record=[{0}]", record);
		return dmSrcTableService.add(record);
	}

	@RequestMapping("addForDraft")
	@ResponseBody
	public DmStrategyPO addForDraft(DmSrcTablePO dstPO, DmPlanPO dpPO) throws BaseAppException, Exception {
		dstPO.setTableNameArray(JsonUtil.toArray(dstPO.getTableName(), TableNamePO.class));
		if (!"[null]".equals(dstPO.getSubTablesStr())) {
			dstPO.setSubTables(JsonUtil.toList(dstPO.getSubTablesStr(), SubTablePO.class));
		}
		List<SubTablePO> subTablePOList = dstPO.getSubTables();
		if (Utils.notEmpty(subTablePOList)) {
			for (int i = 0; i < subTablePOList.size(); i++) {
				if (Utils.isEmpty(subTablePOList.get(i))) {
					subTablePOList.remove(i);
					i--;
					continue;
				}
				subTablePOList.get(i).setSubTableNames(
						JsonUtil.toArray(subTablePOList.get(i).getSubTableName(), TableNamePO.class));
			}
		}
		return dmStrategyService.addSomeInfoOfOneStrategy(dstPO, Status.DRAFT.toString());
	}

	@RequestMapping("addForDraftAtFourthStep")
	@ResponseBody
	public int addForDraftAtFourthStep(DmTargetTablePO dttPO, DmSrcTablePO dstPO) throws BaseAppException, Exception {
		// 源表
		dstPO.setTableNameArray(JsonUtil.toArray(dstPO.getTableName(), TableNamePO.class));
		if (!"[null]".equals(dstPO.getSubTablesStr())) {
			dstPO.setSubTables(JsonUtil.toList(dstPO.getSubTablesStr(), SubTablePO.class));
		}
		List<SubTablePO> subTablePOList = dstPO.getSubTables();
		if (Utils.notEmpty(subTablePOList)) {
			for (int i = 0; i < subTablePOList.size(); i++) {
				if (Utils.isEmpty(subTablePOList.get(i))) {
					subTablePOList.remove(i);
					i--;
					continue;
				}
				subTablePOList.get(i).setSubTableNames(
						JsonUtil.toArray(subTablePOList.get(i).getSubTableName(), TableNamePO.class));
			}
		}
		dmStrategyService.addSomeInfoOfOneStrategy(dstPO, Status.DRAFT.toString());
		DmPlanPO dpPO = dmPlanService.selectByPrimaryKey(dstPO.getDmPlanId());
		if (dpPO.getOperType() == 0) {// 需要备份
			// 目标表
			dttPO.setTargetTables(JsonUtil.toList(dttPO.getTargetTableStr(), TargetTablePO.class));
			dttPO.setTargetColMapList(JsonUtil.toList(dttPO.getTargetColMaps(), Object.class));
			List<TargetTablePO> targetTablePOList = dttPO.getTargetTables();
			for (int i = 0; i < targetTablePOList.size(); i++) {
				if ("".equals(targetTablePOList.get(i).getSrcTableName())) {
					targetTablePOList.remove(i);
					break;
				}
				targetTablePOList.get(i).setTargetTableNamePO(
						JsonUtil.toArray(targetTablePOList.get(i).getTargetTableName(), TableNamePO.class));
			}
			dmTargetTableService.addWithOther(dttPO, Status.DRAFT.toString());
		}
		return 1;
	}

	@RequestMapping("update")
	@ResponseBody
	public DmSrcTablePO update(DmSrcTablePO record) throws BaseAppException {
		logger.debug("modify record begin...record=[{0}]", record);
		dmSrcTableService.update(record);
		return record;
	}

	@RequestMapping("delete")
	@ResponseBody
	public int delete(DmSrcTablePO record) throws BaseAppException {
		logger.debug("delete record begin...record=[{0}]", record);
		return dmSrcTableService.delete(record);
	}

	@RequestMapping("qryRecordInfo")
	@ResponseBody
	public DmSrcTablePO qryRecordInfo(@RequestParam(value = "sourceDataId", required = true) Integer sourceDataId)
			throws Exception {
		DmSrcTablePO record = dmSrcTableService.selectByPrimaryKey(sourceDataId);
		return record;
	}

}
